package xuegao.study.mall.file.controller;

import com.alibaba.fastjson.JSONObject;
import io.minio.MinioClient;
import io.minio.PostPolicy;
import io.minio.errors.MinioException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import xuegao.study.mall.common.api.CommonResult;
import xuegao.study.mall.file.service.MinioService;
import xuegao.study.mall.file.param.PresignParam;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/admin/file")
public class FileController {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioService minioService;

    @PostMapping("/presign")
    public CommonResult<Map<String, String>> presign(@RequestBody PresignParam presignParam) {
        // 1.如果前端不指定桶，那么给一个默认的
        if(StringUtils.isEmpty(presignParam.getBucket())) {
            presignParam.setBucket("demo");
        }
        // 2.前端不指定文件名称，就给一个UUID
        if (StringUtils.isEmpty(presignParam.getFilename())) {
            presignParam.setFilename(UUID.randomUUID().toString());
        }
        // 如果想要以子目录的方式保存，就在前面加上斜杠来表示
        //  presignParam.setFilename("/2023/" + presignParam.getFilename());
        // 设置凭证过期时间
        ZonedDateTime expirationDate = ZonedDateTime.now().plusMinutes(10);
        // 创建一个凭证
        PostPolicy policy = new PostPolicy(presignParam.getBucket(), presignParam.getFilename(), expirationDate);
        // 限制文件大小，单位是字节byte，也就是说可以设置如：只允许10M以内的文件上传
        //        policy.setContentRange(1, 10 * 1024);
        // 限制上传文件请求的ContentType
        //        policy.setContentType("image/png");
        try {
            // 生成凭证并返回
            final Map<String, String> map = minioClient.presignedPostPolicy(policy);
            for (Map.Entry<String, String> entry : map.entrySet()) {
                System.out.println(entry.getKey() + " = " + entry.getValue());
            }
            return CommonResult.success(map);
        } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return CommonResult.failed();
    }

    @PostMapping("/upload")
    public CommonResult<JSONObject> upload(MultipartFile file) {
        String fileName = fileName(file);
        JSONObject result = minioService.upload(file, fileName);
        return CommonResult.success(result);
    }

    public String fileName(MultipartFile file) {
        String prefix = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + UUID.randomUUID().toString().replace("-", "");
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        return prefix + suffix;

    }
}
